package com.agriculture.monitor.service.impl;

import com.agriculture.monitor.base.ResultInfo;
import com.agriculture.monitor.base.TContext;
import com.agriculture.monitor.constant.Constant;
import com.agriculture.monitor.dto.BasePage;
import com.agriculture.monitor.dto.PasswordRequest;
import com.agriculture.monitor.dto.UserPage;
import com.agriculture.monitor.entity.User;
import com.agriculture.monitor.mapper.UserMapper;
import com.agriculture.monitor.service.IUserService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {


    @Override
    public ResultInfo<?> login(User user) {
        String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().or(v -> v.eq(User::getUsername, user.getUsername())
                .or(v1 -> v1.eq(User::getPhone, user.getUsername())))
                .eq(User::getPassword, password).eq(User::getStatus, 1);
        User u = baseMapper.selectOne(queryWrapper);
        if (null != u) {
            // 生成Token
            String token = Jwts.builder().setSubject(JSONObject.toJSONString(u))
                    .setExpiration(new Date(System.currentTimeMillis() + Constant.TOKEN_EXP_SECENDS * 7))
                    .signWith(SignatureAlgorithm.HS512, Constant.JWT_SECRET).compact();
            u.setToken(token);
            return ResultInfo.OK(u);
        }
        return ResultInfo.FALL("用户名或密码错误");
    }

    @Override
    @Transactional
    public ResultInfo<?> create(User user) {
        if (user.getPhone() == null || user.getUsername() == null || user.getPassword() == null) {
            return ResultInfo.FALL("数据不能为空");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(User::getUsername, user.getUsername());
        boolean exits = baseMapper.selectCount(queryWrapper) > 0;
        if (exits) {
            return ResultInfo.FALL("用户名 ：" + user.getUsername() + "已存在");
        }
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        //md5加密
        String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
        user.setPassword(password);
        user.setUsername(StringUtils.hasText(user.getUsername()) ? user.getUsername() : user.getPhone());
        user.setParentId(TContext.getUserId());
        baseMapper.insert(user);
        return ResultInfo.OK(user);
    }

    @Override
    @Transactional
    public ResultInfo<?> password(PasswordRequest passwordRequest) {
        String password = DigestUtils.md5DigestAsHex(passwordRequest.getOldPassword().getBytes(StandardCharsets.UTF_8));
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(User::getId, TContext.getUserId());
        User u = baseMapper.selectOne(queryWrapper);
        if (u == null || !u.getPassword().trim().equals(password)) {
            return ResultInfo.FALL("密码错误");
        }
        String newPassword = DigestUtils.md5DigestAsHex(passwordRequest.getNewPassword().trim().getBytes(StandardCharsets.UTF_8));
        u.setPassword(newPassword);
        baseMapper.updateById(u);
        return ResultInfo.OK();
    }


    @Override
    public ResultInfo<?> childrenPage(BasePage basePage) {
        Page page = new Page(basePage.getPageCurrent(), basePage.getPageSize());
        Page<User> userList = baseMapper.selectPage(page, new LambdaQueryWrapper<User>()
                .select(User::getId, User::getUsername, User::getPhone, User::getCreateTime)
                .eq(User::getParentId, TContext.getUserId()));
        return ResultInfo.OK(userList);
    }


    @Override
    public Page<User> listPage(UserPage basePage) {
        Page<User> page = new Page(basePage.getPageCurrent(), basePage.getPageSize());
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(!StringUtils.isEmpty(basePage.getUsername()), User::getUsername, basePage.getUsername());
        queryWrapper.like(!StringUtils.isEmpty(basePage.getRemarks()), User::getRemarks, basePage.getRemarks());

        if (!CollectionUtils.isEmpty(basePage.getCreateTime()) && basePage.getCreateTime().size() > 1) {
            queryWrapper.between(User::getCreateTime, basePage.getCreateTime().get(0), basePage.getCreateTime().get(1));
        }

        baseMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Override
    @Transactional
    public ResultInfo change(User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(User::getUsername, user.getUsername());
        queryWrapper.lambda().notIn(User::getId, user.getId());
        boolean exits = baseMapper.selectCount(queryWrapper) > 0;
        if (exits) {
            return ResultInfo.FALL("用户名 ：" + user.getUsername() + "已存在");
        }

        User u = baseMapper.selectById(user.getId());
        if (!u.getPassword().equals(user.getPassword())) {
            String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8));
            user.setPassword(password);
        }

        baseMapper.updateById(user);
        return ResultInfo.OK();
    }

    public static void main(String[] args) {
        String password = DigestUtils.md5DigestAsHex("123456".getBytes(StandardCharsets.UTF_8));
        System.out.println(password);
    }
}
